#pragma once

#include "ISistema.h"
#include "Prueba.h"

class CasoDePrueba : public Prueba
{
public:
	CasoDePrueba(Puntero<ISistema> (*inicializar)(nat VELOCIDAD_OMNIBUS, nat VELOCIDAD_AVION, nat COSTO_OMNIBUS, nat COSTO_AVION, nat CAPACIDAD_OMNIBUS, nat CAPACIDAD_AVION, nat MAX_CIUDADES));
	virtual ~CasoDePrueba();

protected:
	virtual void CorrerPruebaConcreta();
	virtual Cadena GetNombre() const;

private:
	Puntero<ISistema> (*inicializar)(nat VELOCIDAD_OMNIBUS, nat VELOCIDAD_AVION, nat COSTO_OMNIBUS, nat COSTO_AVION, nat CAPACIDAD_OMNIBUS, nat CAPACIDAD_AVION, nat MAX_CIUDADES);
	Puntero<ISistema> InicializarSistema(nat VELOCIDAD_OMNIBUS = 10, nat VELOCIDAD_AVION = 100, nat COSTO_OMNIBUS = 10, nat COSTO_AVION = 20, nat CAPACIDAD_OMNIBUS = 20, nat CAPACIDAD_AVION = 30, nat MAX_CIUDADES = 11);
	void InicializarCiudad(Puntero<ISistema> interfaz);

	bool ignorarOK;
	void Verificar(TipoRetorno obtenido, TipoRetorno esperado, Cadena comentario);
	template <class T>
	void Verificar(const T& obtenido, const T& esperado, Cadena comentario);
	template <class T>
	void VerificarConjuntos(Puntero<Iterador<T>> obtenidos, Puntero<Iterador<T>> esperados, Cadena comentarioEncontrado, Cadena comentarioFalta, Cadena comentarioSobra);
	template <class T>
	void VerificarSecuencias(Puntero<Iterador<T>> obtenidos, Puntero<Iterador<T>> esperados, Cadena comentarioEncontrado, Cadena comentarioFalta, Cadena comentarioSobra);
	template <class T>
	bool SonIguales(Puntero<Iterador<T>> obtenidos, Puntero<Iterador<T>> esperados) const;
	template <class T>
	bool Pertenece(const T& obtenido, Puntero<Iterador<T>> esperados) const;

	void VerificarPresupuesto(Tupla<TipoRetorno, Puntero<Iterador<Tupla<TipoTransporte, Puntero<Iterador<pCiudad>>, nat>>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<Tupla<TipoTransporte, Puntero<Iterador<pCiudad>>, nat>>>> esperado);
	void VerificarHayCamino(Tupla<TipoRetorno, bool> obtenido, Tupla<TipoRetorno, bool> esperado);
	void VerificarCaminoMasCorto(Tupla<TipoRetorno, Puntero<Iterador<Tupla<Puntero<Iterador<pCiudad>>, nat>>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<Tupla<Puntero<Iterador<pCiudad>>, nat>>>> esperado);
	void VerificarTendidoMenorCosto(Tupla<TipoRetorno, nat> obtenido, Tupla<TipoRetorno, nat> esperado);
	void VerificarCaminoMasBaratoNoPasaPor(Tupla<TipoRetorno, Puntero<Iterador<Tupla<Puntero<Iterador<pCiudad>>, nat>>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<Tupla<Puntero<Iterador<pCiudad>>, nat>>>> esperado);
	void VerificarItinerario(Tupla<TipoRetorno, nat, Puntero<Iterador<pCiudad>>> obtenido, Tupla<TipoRetorno, nat, Puntero<Iterador<Puntero<Iterador<pCiudad>>>>> esperados);
	void VerificarItemsValiosos(Tupla<TipoRetorno, nat, Puntero<Iterador<Tupla<Cadena, nat>>>> obtenido, Tupla<TipoRetorno, nat, Puntero<Iterador<Tupla<Cadena, nat>>>> esperado);
	void VerificarCiudadesFijas(Tupla<TipoRetorno, Puntero<Iterador<pCiudad>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<pCiudad>>> esperado);
	void VerificarListCiudades(Tupla<TipoRetorno, Puntero<Iterador<pCiudad>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<pCiudad>>> esperado);
	bool SonIguales(const pCiudad& obtenido, const pCiudad& esperado) const;
	Cadena ObtenerTexto(const pCiudad& c) const;
	bool SonIguales(const Tupla<TipoTransporte, Puntero<Iterador<pCiudad>>, nat>& obtenido, const Tupla<TipoTransporte, Puntero<Iterador<pCiudad>>, nat>& esperado) const;
	Cadena ObtenerTexto(const Tupla<TipoTransporte, Puntero<Iterador<pCiudad>>, nat>& t) const;
	bool SonIguales(const Tupla<Puntero<Iterador<pCiudad>>, nat>& obtenido, const Tupla<Puntero<Iterador<pCiudad>>, nat>& esperado) const;
	Cadena ObtenerTexto(const Tupla<Puntero<Iterador<pCiudad>>, nat>& t) const;
	bool SonIguales(const Tupla<Cadena, nat>& obtenido, const Tupla<Cadena, nat>& esperado) const;
	Cadena ObtenerTexto(const Tupla<Cadena, nat>& t) const;

	Cadena ObtenerTexto(TipoTransporte t) const;
	Cadena ObtenerTexto(nat n) const;
	Cadena ObtenerTexto(Puntero<Iterador<pCiudad>> ciudades) const;

	void PruebaOK1();
	void PruebaOK2();
	void PruebaOK3();
	void PruebaOK4();
	void PruebaOK5();
	void PruebaOK6();
	void PruebaOK7();
	void PruebaOK8();
	void PruebaOK10();

	void PruebaERROR1();
	void PruebaERROR2();
	void PruebaERROR3();
	void PruebaERROR4();
	void PruebaERROR5();
	void PruebaERROR6();
	void PruebaERROR7();
	void PruebaERROR8();
	void PruebaERROR10();

	void InicializarGrafos(Puntero<ISistema> interfaz);
	void InicializarConexiones(Puntero<ISistema> interfaz);
	void InicializarTodo(Puntero<ISistema> interfaz,bool conexo);
};